//
// Created by 朕与将军解战袍 on 2022/3/13.
//

#ifndef TRUETYPERENDER_TTF_TABLES_H
#define TRUETYPERENDER_TTF_TABLES_H

/*
 * 本头文件用于定义 TrueType 字体文件中用到的各个表的结构与常量
 */

// std
#include <stdint.h>
#include <stdalign.h>

/**
 * TTF 中的特殊数据类型
 * TODO shortFrac: 16-bit signed fraction
 * TODO Fixed: 16.16-bit signed fixed-point number
 * TODO F2Dot14: 16-bit signed fixed number with the low 14 bits representing fraction.
 * TODO longDateTime: 没有相应的解析函数
 */
// 16-bit signed fraction
typedef uint16_t shortFrac; // 暂时使用 16-bit 无符号数代替
// 16.16-bit signed fixed-point number
typedef uint32_t Fixed; // 暂时使用 32-bit 无符号数代替
// 16-bit signed integer that describes a quantity in FUnits, the smallest measurable distance in em space.
typedef int16_t  FWord;
// 16-bit unsigned integer that describes a quantity in FUnits, the smallest measurable distance in em space.
typedef uint16_t uFWord;
// 16-bit signed fixed number with the low 14 bits representing fraction.
typedef uint16_t F2Dot14; // 暂时使用 16-bit 无符号数代替
// The long internal format of a date in seconds since 12:00 midnight, January 1, 1904.
// It is represented as a signed 64-bit integer.
typedef int64_t  longDateTime;

typedef struct ttf_offset_sub_table {
    uint32_t scalerType;
    uint16_t numTables;
    uint16_t searchRange;
    uint16_t entrySelector;
    uint16_t rangeShift;
} OffsetSubtable;


typedef struct ttf_table_dir {
    uint32_t tag;
    uint32_t checkSum;
    uint32_t offset;
    uint32_t length;
} TableDir;

/**
 * The required tables tag
 */
#define TAG_CMAP ((uint32_t)0x636D6170)
#define TAG_GLYF ((uint32_t)0x676C7966)
#define TAG_HEAD ((uint32_t)0x68656164)
#define TAG_HHEA ((uint32_t)0x68686561)
#define TAG_HMTX ((uint32_t)0x686D7478)
#define TAG_LOCA ((uint32_t)0x6C6F6361)
#define TAG_MAXP ((uint32_t)0x6D617870)
#define TAG_NAME ((uint32_t)0x6E616D65)
#define TAG_POST ((uint32_t)0x706F7374)

/**
 * The optional tables tag
 */
#define TAG_CVT_ ((uint32_t)0x63767420)
#define TAG_FPGM ((uint32_t)0x6670676D)
#define TAG_HDMX ((uint32_t)0x68646D78)
#define TAG_KERN ((uint32_t)0x6B65726E)
#define TAG_OS_2 ((uint32_t)0x4F532F32)
#define TAG_PREP ((uint32_t)0x70726570)

#pragma pack(1)
typedef struct ttf_head_table {
    Fixed version;
    Fixed fontRevision;
    uint32_t checkSumAdjustment;
    uint32_t magicNumber; // set to 0x5F0F3CF5
    uint16_t flags;       // TODO 解析 flags
    uint16_t unitsPerEm;  // range from 64 to 16384
    longDateTime created;
    longDateTime modified;
    FWord xMin;
    FWord yMin;
    FWord xMax;
    FWord yMax;
    uint16_t macStyle;
    uint16_t lowestRecPPEM;
    int16_t fontDirectionHint;
    int16_t indexToLocFormat;
    int16_t glyphDataFormat;
} HeadTable;

#define HEAD_TABLE_MAGIC_NUM ((uint32_t)(0x5F0F3CF5))

/**
 * 用于解析 macStyle
 */
#define MAC_STYLE_BOLD      ((uint16_t) (1 << 0))
#define MAC_STYLE_ITALIC    ((uint16_t) (1 << 1))
#define MAC_STYLE_UNDERLINE ((uint16_t) (1 << 2))
#define MAC_STYLE_OUTLINE   ((uint16_t) (1 << 3))
#define MAC_STYLE_SHADOW    ((uint16_t) (1 << 4))
#define MAC_STYLE_CONDENSED ((uint16_t) (1 << 5))
#define MAC_STYLE_EXTENDED  ((uint16_t) (1 << 6))

/**
 * 用于解析 fontDirectionHint
 */
#define FONT_DIR_MIXED      ((int16_t)0)
#define FONT_DIR_L_TO_R     ((int16_t)1)
#define FONT_DIR_L_TO_R_N   ((int16_t)2)
#define FONT_DIR_R_TO_L     ((int16_t)-1)
#define FONT_DIR_R_TO_L_N   ((int16_t)-2)

/**
 * 用于解析 indexToLocFormat
 */
#define LOCA_FORMAT_SHORT   ((int16_t)0)
#define LOCA_FORMAT_LONG    ((int16_t)1)

typedef struct ttf_maxp_table {
    Fixed version; // 0x00010000 (1.0)
    uint16_t numGlyphs;
    uint16_t maxPoints;
    uint16_t maxContours;
    uint16_t maxComponentPoints;
    uint16_t maxComponentContours;
    uint16_t maxZones; // set to 2 (经过测试，并没有设置为 2)
    uint16_t maxTwilightPoints;
    uint16_t maxStorage;
    uint16_t maxFunctionDefs;
    uint16_t maxInstructionDefs;
    uint16_t maxStackElements;
    uint16_t maxSizeOfInstructions;
    uint16_t maxComponentElements;
    uint16_t maxComponentDepth;
} MaxpTable;

typedef struct ttf_cmap_idx {
    uint16_t version;
    uint16_t numsSubTables;
} CmapIndex;

#pragma pack(1)
typedef struct ttf_cmap_subtable {
    uint16_t platformID;
    uint16_t platformSpecificID;
    uint32_t offset;
} CmapSubTable;

/**
 * Platform ID
 */
#define PLATFORM_ID_UNICODE   ((uint16_t)0)
#define PLATFORM_ID_MACINTOSH ((uint16_t)1)
#define PLATFORM_ID_MICROSOFT ((uint16_t)3)

/**
 * Platform Specific ID (Unicode)
 */
#define UNICODE_VERSION_1_0 ((uint16_t)0)
#define UNICODE_VERSION_1_1 ((uint16_t)1)
#define UNICODE_ISO         ((uint16_t)2)
#define UNICODE_2_BMP       ((uint16_t)3)
#define UNICODE_2_NON_BMP   ((uint16_t)4)
#define UNICODE_VAR_SEQ     ((uint16_t)5)
#define UNICODE_LAST_RESORT ((uint16_t)6)

/**
 * Platform Specific ID (Macintosh)
 */
#define MACINTOSH_ROMAN     ((uint16_t)0)
#define MACINTOSH_JAPANESE  ((uint16_t)1)
#define MACINTOSH_TRAD_ZH   ((uint16_t)2)
#define MACINTOSH_KOREN     ((uint16_t)3)
#define MACINTOSH_ARABIC    ((uint16_t)4)
#define MACINTOSH_HEBREW    ((uint16_t)5)
#define MACINTOSH_GREEK     ((uint16_t)6)
#define MACINTOSH_RUSSIAN   ((uint16_t)7)
#define MACINTOSH_RSYMBOL   ((uint16_t)8)
#define MACINTOSH_DEVANGARI ((uint16_t)9)
#define MACINTOSH_GURMUKHI  ((uint16_t)10)
#define MACINTOSH_GUJARATI  ((uint16_t)11)
#define MACINTOSH_ORIYA     ((uint16_t)12)
#define MACINTOSH_BENGALI   ((uint16_t)13)
#define MACINTOSH_TAMIL     ((uint16_t)14)
#define MACINTOSH_TELUGU    ((uint16_t)15)
#define MACINTOSH_KANNADA   ((uint16_t)16)
#define MACINTOSH_MALAYALAM ((uint16_t)17)
#define MACINTOSH_SINHALESE ((uint16_t)18)
#define MACINTOSH_BURMESE   ((uint16_t)19)
#define MACINTOSH_KHMER     ((uint16_t)20)
#define MACINTOSH_THAI      ((uint16_t)21)
#define MACINTOSH_LAOTIAN   ((uint16_t)22)
#define MACINTOSH_GEORGIAN  ((uint16_t)23)
#define MACINTOSH_ARMENIAN  ((uint16_t)24)
#define MACINTOSH_SIMP_ZH   ((uint16_t)25)
#define MACINTOSH_TIBETAN   ((uint16_t)26)
#define MACINTOSH_MONGOLIAN ((uint16_t)27)
#define MACINTOSH_GEEZ      ((uint16_t)28)
#define MACINTOSH_SLAVIC    ((uint16_t)29)
#define MACINTOSH_VIETNAMESE ((uint16_t)30)
#define MACINTOSH_SINDHI    ((uint16_t)31)

/**
 * Platform Specific ID (Windows)
 */
#define WINDOWS_SYMBOL      ((uint16_t)0)
#define WINDOWS_UNICODE_BMP ((uint16_t)1)
#define WINDOWS_SHIFT_JIS   ((uint16_t)2)
#define WINDOWS_PRC         ((uint16_t)3)
#define WINDOWS_BIG_FIVE    ((uint16_t)4)
#define WINDOWS_JOHAB       ((uint16_t)5)
#define WINDOWS_UNICODE_UCS ((uint16_t)10)

#define CMAP_FORMAT_0       ((uint16_t)0)
#define CMAP_FORMAT_2       ((uint16_t)2)
#define CMAP_FORMAT_4       ((uint16_t)4)
#define CMAP_FORMAT_6       ((uint16_t)6)
#define CMAP_FORMAT_8       ((uint16_t)8)
#define CMAP_FORMAT_10      ((uint16_t)10)
#define CMAP_FORMAT_12      ((uint16_t)12)
#define CMAP_FORMAT_13      ((uint16_t)13)
#define CMAP_FORMAT_14      ((uint16_t)14)


typedef struct cmap_format_4 {
//    uint16_t  format;
    uint16_t  length;
    uint16_t  lang;
    uint16_t  segCount;
    uint16_t  searchRange;
    uint16_t  entrySelector;
    uint16_t  rangeShift;
    uint16_t* endCode;
//    uint16_t  reservedPad;
    uint16_t* startCode;
    uint16_t* idDelta;
    uint16_t* idRangeOffset;
    uint16_t* glyphIndexArray;
} CmapFormat4;

/**
 * 用于解析 glyphDataFormat
 */
#define GLYPH_FORMAT_CURRENT ((int16_t)0)



#endif //TRUETYPERENDER_TTF_TABLES_H
